package gov.pbc.nn.kjgl.software.dao;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import com.bstek.bdf2.core.context.ContextHolder;
import com.bstek.dorado.core.Configure;
import com.bstek.dorado.data.entity.EntityState;
import com.bstek.dorado.data.entity.EntityUtils;
import com.bstek.dorado.data.provider.Criteria;
import com.bstek.dorado.data.provider.Page;

import gov.pbc.nn.core.dao.AbstractHibernateDao;
import gov.pbc.nn.core.dao.CommonJdbcDao;
import gov.pbc.nn.kjgl.entity.Project;
import gov.pbc.nn.kjgl.entity.ProjectFile;
import gov.pbc.nn.kjgl.entity.ProjectTask;

@Repository
public class ProjectTaskDao extends AbstractHibernateDao {

	@Resource(name = CommonJdbcDao.BEAN_ID)
	private CommonJdbcDao commonJdbcDao;

	public void loadProject(Page<Project> page, Criteria criteria) {
		String hql = "select distinct projectId from ProjectMember where  invalid=false and username=:username";
		String username = ContextHolder.getLoginUser().getUsername();
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("username", username);
		List<String> ls = this.query(hql, map);
		if (ls.size() > 0) {
			DetachedCriteria query = this.buildDetachedCriteria(criteria, Project.class);
			query.add(Restrictions.or(Restrictions.eq("invalid", false), Restrictions.isNull("invalid")));
			query.add(Restrictions.eq("state", 10));
			query.add(Restrictions.in("id", ls));
			this.pagingQuery(page, query);
		}
	}

	public List<Map<String, Object>> loadDropDown(Map<String, Object> parameter) {
		String hql = "select distinct username from ProjectMember where invalid=false and projectId=:projectId";
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("projectId", parameter.get("projectId"));
		List<String> ls = this.query(hql, map);
		List<Map<String, Object>> values = new ArrayList<Map<String, Object>>();
		if (!ls.isEmpty()) {
			for (int i = 0; i < ls.size(); i++) {
				Map<String, Object> m = new HashMap<String, Object>();
				m.put("username", ls.get(i));
				values.add(m);
			}
		}
		return values;
	}

	public void loadProjectTask(Page<ProjectTask> page, String projectId, Criteria criteria) {
		DetachedCriteria query = this.buildDetachedCriteria(criteria, ProjectTask.class);
		query.add(Restrictions.or(Restrictions.eq("invalid", false), Restrictions.isNull("invalid")));
		query.add(Restrictions.eq("projectId", projectId));
		this.pagingQuery(page, query);
	}

	public void loadMyProjectTask(Page<ProjectTask> page, String projectId, Criteria criteria) {
		DetachedCriteria query = this.buildDetachedCriteria(criteria, ProjectTask.class);
		String username = ContextHolder.getLoginUser().getUsername();
		query.add(Restrictions.or(Restrictions.eq("invalid", false), Restrictions.isNull("invalid")));
		query.add(Restrictions.eq("projectId", projectId));
		query.add(Restrictions.eq("person", username));
		this.pagingQuery(page, query);
	}

	public List<ProjectFile> loadProjectFileByProjectTaskId(String projectid) {
		String hql = "from ProjectFile where invalid=false and ownerId=:id";
		List<ProjectFile> values = new ArrayList<ProjectFile>();
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("id", projectid);
		values = this.query(hql, map);
		if (!values.isEmpty()) {
			return values;
		}
		return null;
	}

	public List<String> loadTaskFileByTaskId(String taskId) {
		String hql = "select attachments from ProjectTask where invalid=false and id=:taskId";
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("taskId", taskId);
		return this.query(hql, map);
	}

	public void saveProjectTask(ProjectTask projectTask, String Id) throws IOException {
		EntityState state = EntityUtils.getState(projectTask);
		if (state.equals(EntityState.NEW)) {
			projectTask.setBeginTime(new Date());
			projectTask.setCreateUser(ContextHolder.getLoginUserName());
			projectTask.setProjectId(Id);
			this.save(projectTask);
			List<ProjectFile> files = EntityUtils.getValue(projectTask, "projectFile");
			if (files != null) {
				Map<String, String> tmpMap = new HashMap<String, String>();
				for (int i = 0; i < files.size(); i++) {
					ProjectFile pf = files.get(i);
					pf.setOwnerId(projectTask.getId());
					pf.setType(2);
					tmpMap.put("File" + i, pf.getPath());
					pf.setPath(this.getRealPath().toString());
					this.save(pf);
				}
				for (int i = 0; i < files.size(); i++) {
					ProjectFile pf = files.get(i);
					String key = "File" + i;
					String tmpPath = tmpMap.get(key);
					this.transterFile(tmpPath, pf.getPath());
				}
			}
		} else if (state.equals(EntityState.MODIFIED)) {
			this.update(projectTask);
		}
	}

	public void deleteProjectTask(List<String> list) {
		String hql = "select id from ProjectFile where invalid=false and ownerId=:id";
		Map<String, Object> map = new HashMap<String, Object>();
		for (String id : list) {
			map.put("id", id);
			List<String> ls = this.query(hql, map);
			if (ls.size() > 0) {
				for (String pid : ls) {
					this.delete(pid, ProjectFile.class);
				}
			}
			this.delete(id, ProjectTask.class);
		}
	}

	public Path getRealPath() throws IOException {
		String basePath = Configure.getString("WENJIAN_FILE_UPLOAD_PATH");
		String pathArr = "任务附件";
		Path path = Paths.get(basePath, pathArr);
		if (!Files.isDirectory(path)) {
			path = Files.createDirectories(path);
		}
		path = path.resolve(UUID.randomUUID().toString());
		return path;// 上传文件保存后的实际地址
	}

	private void transterFile(String sourceFile, String targetFile) throws IOException {
		Path sourcePath = Paths.get(sourceFile);
		Files.copy(sourcePath, Paths.get(targetFile));
	}

}
